﻿using PlantsZombies.Common.Card;
using PlantsZombies.View.ViewEx;
using System;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace PlantsZombies.Common.CardTool
{
    public unsafe class GameCardTool : IDisposable
    {
        public int _startX = 350;
        public int _startY = 170;
        public int _cellWidth = 110;
        public int _cellHeight = 130;
        public float _zoomX = 1f;
        public float _zoomY = 1f;
        private ImageObject[] _bitmapsSunflowerBullet;
        public GameCardTool()
        {
            brushOut = new SolidBrush(OutColor);
            brushInner = new SolidBrush(InColor);
            polygonSb=new SolidBrush(Color.Gray);
        }
        public void SetBullet(ImageObject[] bitmapsSunflowerBullet)
        {
            _bitmapsSunflowerBullet = bitmapsSunflowerBullet;
        }
        public void MouseDown(object sender, MouseEventArgs e)
        {
            if(pointsLeft==null || pointsRight==null) return;

            if (IsPointInTriangle(pointsLeft[0], pointsLeft[1], pointsLeft[2], e.Location))
            {
                if (_pageIndex > 0)
                    _pageIndex -= pageSize;
            }
            else if (IsPointInTriangle( pointsRight[0], pointsRight[1], pointsRight[2], e.Location))
            {
                if(_pageIndex+5<= _cardObjects.Length)
                    _pageIndex += pageSize;
            }
        }
        public void SizeChange(int startX, int startY, int cellWidth, int cellHeight, float zoomX, float zoomY)
        {
            this._startX = startX;
            this._startY = startY;
            this._cellWidth = cellWidth;
            this._cellHeight = cellHeight;
            this._zoomX = zoomX;
            this._zoomY = zoomY;
            if (_cardObjects != null)
            {
                fixed (CardObject* cardPtr = _cardObjects)
                {
                    for (int i = 0; i < _cardObjects.Length; i++)
                    {
                        CardObject* ptr = cardPtr + i;
                        ptr->UpdateSize(zoomX, zoomY);
                    }
                }
            }
        }
        CardObject[] _cardObjects;
        public CardObject[] Cards { get { return _cardObjects; } }
        public void SetCards(CardObject[] cardObjects)
        {
            _cardObjects = cardObjects;
        }
        private int _radius = 10;
        public int Radius
        {
            get { return _radius; }
            set
            {
                if (value < 0 || value == _radius) return;
                _radius = value;
            }
        }
        private Padding _borderPadding = new Padding(10, 10, 10, 10);
        public Padding BorderPadding
        {
            get { return _borderPadding; }
            set
            {
                _borderPadding = value;
            }
        }
        private Color _outColor = Color.FromArgb(141, 66, 42);
        public Color OutColor
        {
            get { return _outColor; }
            set
            {
                _outColor = value;
                brushOut.Dispose();
                brushOut = new SolidBrush(OutColor);
            }
        }
        private Color _inColor = Color.FromArgb(103, 46, 17);
        public Color InColor
        {
            get { return _inColor; }
            set
            {
                _inColor = value;
                brushInner.Dispose();
                brushInner = new SolidBrush(InColor);
            }
        }
        private int _sunflowerCount = 125;
        public int SunflowerCount
        {
            get { return _sunflowerCount; }
            set { _sunflowerCount = value; }
        }
        #region 分页显示卡片
        const int pageSize = 5;
        int _pageIndex = 0;
        bool IsPointInTriangle(Point A, Point B, Point C, Point P)
        {
            int cross1 = CrossProduct(A, B, P);
            int cross2 = CrossProduct(B, C, P);
            int cross3 = CrossProduct(C, A, P);

            bool hasNeg = (cross1 < 0) || (cross2 < 0) || (cross3 < 0);
            bool hasPos = (cross1 > 0) || (cross2 > 0) || (cross3 > 0);

            return !(hasNeg && hasPos);
        }
        int CrossProduct(Point v1, Point v2, Point v3)
        {
            int x1 = v2.X - v1.X;
            int y1 = v2.Y - v1.Y;
            int x2 = v3.X - v1.X;
            int y2 = v3.Y - v1.Y;
            return x1 * y2 - y1 * x2;
        }
        #endregion
        Pen penCard = new Pen(Color.FromArgb(89, 46, 44), 3);
        Brush brushOut;
        Brush brushInner;
        int _cardBackgroundWidth = 540;
        int _cardBackgroundHeight = 90;
        SizeF _sunflowerSF = SizeF.Empty;
        SolidBrush _priceSB = new SolidBrush(Color.White);
        private int _curIndex = 0;
        SolidBrush polygonSb;
        Point[] pointsLeft;
        Point[] pointsRight;
        const int hp = 10;
        const int xp = 10;
        public void DrawTool(Graphics g, Font font)
        {
            Rectangle rect = new Rectangle(_startX, 0, (int)(_cardBackgroundWidth * _zoomX), (int)(_cardBackgroundHeight * _zoomY));
            int radius = Radius;
            GraphicsPath path = GetRoundedRectangle(rect, radius);

            g.FillPath(brushOut, path);
            g.DrawPath(penCard, path);

            Rectangle rectInner = new Rectangle(rect.Left + BorderPadding.Left, rect.Top + BorderPadding.Top,
                (int)(80 * _zoomY), rect.Height - BorderPadding.Top - BorderPadding.Bottom);
            GraphicsPath pathInner = GetRoundedRectangle(rectInner, radius);

            g.FillPath(brushInner, pathInner);
            g.DrawPath(penCard, pathInner);

            Rectangle rectInner2 = new Rectangle(rectInner.X + rectInner.Width + BorderPadding.Left,
                rect.Top + BorderPadding.Top,
               rect.Width - BorderPadding.Right - BorderPadding.Left - rectInner.Width - BorderPadding.Left,
               rect.Height - BorderPadding.Top - BorderPadding.Bottom);
            GraphicsPath pathInner2 = GetRoundedRectangle(rectInner2, radius);
            g.FillPath(brushInner, pathInner2);
            g.DrawPath(penCard, pathInner2);

          
            // 绘制多选按钮
            const int multipleSize = 20;
            int multipleWidth =(int)(multipleSize * _zoomX);
            int multipleHeight = (int)(multipleSize * _zoomY);
            int middleY = rectInner2.Y+(hp>>1) + (rectInner2.Height - multipleHeight >> 1);
            int mx = rectInner2.X + (hp >> 1);
            pointsLeft = new Point[]
            {
                new Point(mx,middleY),
                new Point(mx+multipleWidth, middleY-(multipleHeight>>1)),
                new Point(mx+multipleWidth,  middleY+(multipleHeight>>1))
            };
            g.FillPolygon(polygonSb, pointsLeft); // 填充三角形
            mx= rectInner2.Right- (hp >> 1)- multipleWidth;
            pointsRight = new Point[]
            {
                new Point(mx+multipleWidth,middleY),
                new Point(mx, middleY-(multipleHeight>>1)),
                new Point(mx,  middleY+(multipleHeight>>1))
            };
            g.FillPolygon(polygonSb, pointsRight); // 填充三角形
            // 绘制卡片
            if (_cardObjects != null)
            {
                fixed (CardObject* cardPtr = _cardObjects)
                {
                    int startX = rectInner2.X+ multipleWidth + xp;
                    int startY = rectInner2.Y + hp;
                    int pageCount = 0;
                    for (int i = _pageIndex; i < _cardObjects.Length; i++)
                    {
                        if (pageCount++ == pageSize) break;

                        var ptr = cardPtr + i;
                        int cw = ptr->CardSize.Width;
                        ptr->StartX = startX;
                        ptr->StartY = startY;
                        ptr->ZoomX = _zoomX;
                        ptr->ZoomY = _zoomY;
                        ptr->DrawCard(g, font, _priceSB);
                        startX += cw + (xp>>1);
                    }
                }
            }
            // 太阳花
            var img = _bitmapsSunflowerBullet[_curIndex];
            IntPtr hdc = g.GetHdc();
            GDI32.DrawImageTransparenc(hdc, img.BitmapPtr, rectInner.X + (int)((rectInner.Width - 60 * _zoomX) / 2), rectInner.Y, img.Width, img.Height, (int)(60 * _zoomX), (int)(60 * _zoomY));
            g.ReleaseHdc(hdc);
            if (++_curIndex >= _bitmapsSunflowerBullet.Length)
                _curIndex = 0;
            string str = _sunflowerCount.ToString();
            SizeF sf = str.MeasureString(font);
            g.DrawString(str, font, _priceSB, rectInner.X + (rectInner.Width - 60 * _zoomX) / 2 + (60 * _zoomX - sf.Width) / 2, rectInner.Y + 60 * _zoomY);
            path.Dispose();
            pathInner.Dispose();
            pathInner2.Dispose();
        }
        private GraphicsPath GetRoundedRectangle(Rectangle rect, int radius)
        {
            GraphicsPath path = new GraphicsPath();
            var r = radius << 1;
            path.AddArc(rect.X, rect.Y, r, r, 180, 90);
            path.AddLine(rect.X + radius, rect.Y, rect.Right - r, rect.Y);
            path.AddArc(rect.Right - r, rect.Y, r, r, 270, 90);
            path.AddLine(rect.Right, rect.Y + r, rect.Right, rect.Bottom - r);
            path.AddArc(rect.Right - r, rect.Bottom - r, r, r, 0, 90);
            path.AddLine(rect.Right - r, rect.Bottom, rect.X + r, rect.Bottom);
            path.AddArc(rect.X, rect.Bottom - r, r, r, 90, 90);
            path.AddLine(rect.X, rect.Bottom - r, rect.X, rect.Y + radius);

            return path;
        }
        public void Dispose()
        {
            penCard.Dispose();
            brushOut.Dispose();
            brushInner.Dispose();
            _priceSB.Dispose();
        }
    }
}
